<template>
  <div class="view-main">
    <div class="view-2d">
      <div class="view-container" ref="view-container-2d"></div>
    </div>
  </div>
</template>

<script lang="ts">
import { Vue, Component, Watch } from "vue-property-decorator";
import { init as arcgisInit, getModules } from "@/assets/modules/arcgisAPI";
import { createLayer } from "@/assets/modules/esriLayer";
import { getInitMapConfig } from "@/assets/modules/service";
import store from "@/assets/modules/store";
@Component({
  name: "ViewComponent"
})
export default class extends Vue {
  private mapView: any = null;

  private mapConfig: any = null;

  private extent2d: any = null;

  private recursive2DArray: any[] = [];

  mounted() {
    // api初始化
    arcgisInit();
    // 地图参数设置
    const win: any = window;
    this.mapConfig = win.mapConfig;
    store.spatialReference = this.mapConfig.spatialReference;
    store.constraint = this.mapConfig.constraint;
    this.extent2d = this.mapConfig.extent2D;
    // 将初始位置存到store中，用于复位
    this.$store.commit("view/setInitialExtent2d", this.extent2d);
    this.createView();
  }

  // 创建视图
  async createView() {
    let view: any = null;

    if (!this.mapView) {
      view = await this.createView2d();
    }

    if (view) {
      // 删除多余组件
      const promise = new Promise((resolve, reject) => {
        view.ui.remove("attribution");
        view.ui.empty("top-left");
        view.ui.empty("top-right");
        view.when(() => {
          this.$store.commit("view/setLoaded2d", true);

          resolve(view);
        });
        view.on("click", () => {
          console.log(view.scale);
          console.log(view.camera);
        });
      });
      return promise;
    }
  }

  // 创建2d视图
  async createView2d() {
    try {
      const modules = await getModules(["esri/views/MapView"]);
      const [MapView] = modules;
      // 底图
      const basemap = await this.createBasemap();
      console.log(basemap);
      // 地图
      const map = await this.createMap(basemap);
      const dom = this.$refs["view-container-2d"] as HTMLDivElement;
      const view = new MapView({
        container: dom,
        map,
        spatialReference: store.spatialReference,
        extent: {
          xmin: this.extent2d.xMin,
          xmax: this.extent2d.xMax,
          ymin: this.extent2d.yMin,
          ymax: this.extent2d.yMax,
          spatialReference: store.spatialReference
        },
        constraints: store.constraint || null
      });
      store.mapView = view;
      this.mapView = view;

      return view;
    } catch (e) {
      console.error(e);
    }
  }

  // 创建地图对象
  private async createMap(basemap: any) {
    const modules = await getModules(["esri/Map"]);
    const [Map] = modules;
    // 地图对象
    const map = new Map({
      basemap
    });
    return map;
  }

  // 创建底图tuc
  private async createBasemap() {
    const layers = await this.createBaseLayer();
    const modules = await getModules(["esri/Basemap"]);
    const [Basemap] = modules;

    const basemap = new Basemap({
      baseLayers: layers,
      referenceLayers: []
    });
    return basemap;
  }

  // 创建底图图层
  private createBaseLayer() {
    const promise = new Promise((resolve, reject) => {
      this.getBaselayerOpiton().then(options => {
        const arr: Promise<any>[] = [];
        let parentName = options.length > 0 ? options[0].parentName : "";
        options.forEach(el => {
          // 图层类型
          el.layerType = el.mapLayer.layerConfig.layerType;
          el.checked = el.parentName === parentName;
          arr.push(createLayer(el));
        });
        Promise.all(arr).then(res => {
          resolve(res);
        });
      });
    });
    return promise;
  }

  // 获取配置的底图
  private getBaselayerOpiton() {
    const win: any = window;
    const param: any = {
      cateSfid: win.initMap.init2D
    };
    if (
      this.mapConfig.base2DMapCategoryId &&
      this.mapConfig.base2DMapCategoryId != ""
    ) {
      param.parentSfid = this.mapConfig.base2DMapCategoryId;
    }
    const promise = new Promise<any[]>((resolve, reject) => {
      getInitMapConfig(param).then((res: any) => {
        console.log(res);
        if (res?.data?.length > 0) {
          this.recursive2DArray = [];
          let initTree: any = [];
          const data = res.data;
          data.forEach((item: any) => {
            this.recursiveNode(item, true, item?.name);
            item.displayName = item?.name;
            initTree.push(item);
          });
          if (this.recursive2DArray.length === 0) {
            return;
          }
          this.$store.commit(
            "view/setBaseLayer2d",
            JSON.parse(JSON.stringify(initTree))
          );
        }
        resolve(this.recursive2DArray);
      });
    });
    return promise;
  }

  // 递归节点数组
  recursiveNode(nodeValue: any, is2D: boolean, parentName = "") {
    if (!nodeValue) {
      return;
    }
    if (Array.isArray(nodeValue) && nodeValue?.length > 0) {
      nodeValue.forEach(item => {
        this.addNode(item, is2D, parentName);
      });
    } else {
      this.addNode(nodeValue, is2D, parentName);
    }
  }
  addNode(node: any, is2D: boolean, parentName = "") {
    const hasChildrenAttr = (obj: any) => {
      return obj?.children?.length > 0;
    };
    if (hasChildrenAttr(node)) {
      this.recursiveNode(node.children, is2D, parentName);
    } else if (node?.layers?.length > 0) {
      this.transferrerParam(node, is2D, parentName);
      if (is2D) {
        this.recursive2DArray.push(node);
      }
    }
  }
  //新旧参数中转
  transferrerParam(data: any, is2D = true, parentName = "") {
    if (!data) return null;
    try {
      data.mapLayer = data?.layers?.[0] || null;
      if (data.mapLayer) {
        data.mapLayer = {
          ...data.mapLayer,
          serviceUrl: data.mapLayer?.layerUrl,
          displayName: data.mapLayer?.name,
          id: data.mapLayer?.sfid,
          opacity: data?.detail?.opacity || 0,
          checked: data?.detail?.defaultDisplay === 1 ? true : false,
          parentName: parentName,
          layerConfig: {
            layerType: parseInt(data?.mapLayer?.layerType || 7)
          }
        };
        data.layerConfig = {
          layerType: parseInt(data?.mapLayer?.layerType || 7)
        };
        data.displayName = data.mapLayer?.name;
        (data.opacity = data?.detail?.opacity || 0),
          (data.checked = data?.detail?.defaultDisplay === 1 ? true : false);
        data.labelEnabled = data?.detail?.displayLabel === 1 ? true : false;
        data.parentName = parentName || "";
        data.layerType = parseInt(data?.mapLayer?.layerType || 7);
        // 专题图层里面也有底图id，需区别开来
        data.mapLayer.id = is2D
          ? data?.mapLayer?.id + "-basemap"
          : data?.mapLayer?.id + "3D";
      }
    } catch (error) {
      console.log(error);
    }
  }
}
</script>

<style lang="scss" scoped>
.view-main {
  width: 100%;
  height: 100%;
  pointer-events: auto;
  .view-2d {
    width: 100%;
    height: 100%;
    .view-container {
      width: 100%;
      height: 100%;
    }
  }
}
</style>
<style>
.esri-view .esri-view-surface--inset-outline:focus::after {
  outline: auto 0px !important;
}
</style>
